package server.service;

import common.Message;

import common.MessageStatus;
import common.User;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

public class ServerService {
    private ServerSocket server;

    //用户不可以同名，但是是用String，所以不用重写hashcode和equals
    public static ConcurrentHashMap<String,User> exitUsers=new ConcurrentHashMap<>();

    //
    public static ConcurrentHashMap<String, ArrayList<Message>> messages=new ConcurrentHashMap<>();

    static {
        exitUsers.put("李王",new User("李王","123456"));
        exitUsers.put("李若",new User("李若","123456"));
        exitUsers.put("李黄",new User("李黄","123456"));
        exitUsers.put("李涵",new User("李涵","123456"));
        exitUsers.put("十号",new User("十号","123456"));
        exitUsers.put("石昊",new User("石昊","123456"));
    }

    //创建消息列表给每个用户
    static {
        Iterator<String> iterator = exitUsers.keySet().iterator();
        while(iterator.hasNext()){
            messages.put(exitUsers.get(iterator.next()).getId(),new ArrayList<Message>());
        }
    }

    public void listening(){
        try {
            server=new ServerSocket(9999);

            //一直监听
            while(true) {
                System.out.println("正在监听9999端口");
                Socket socket = server.accept();

                ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream());
                ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream());

                User user= (User)objIn.readObject();

                //待发送
                Message message = new Message();

                if(!exitUsers.containsKey(user.getId())){
                    System.out.println(user.getId()+" 不存在，无法登录");
                    message.setType(MessageStatus.USERID_ERROR);
                    objOut.writeObject(message);
                    objOut.flush();
                    socket.close();
                    continue;
                }else if(!exitUsers.get(user.getId()).getPassword().equals(user.getPassword())){
                    System.out.println(user.getId()+" 密码错误，无法登录");
                    message.setType(MessageStatus.PASSWORD_ERROR);
                    objOut.writeObject(message);
                    objOut.flush();
                    socket.close();
                    continue;
                }

                if(SocketThreadManager.isExitUser(user.getId())){
                    System.out.println(user+" 已经在线，不能再登录");
                    message.setType(MessageStatus.IS_ONLINE);
                    objOut.writeObject(message);
                    objOut.flush();
                    socket.close();
                    continue;
                }

                //发送成功message给Client
                System.out.println(user+" 成功登录");
                message.setType(MessageStatus.LOGIN_SUCCEED);

                int offline_messagesLength=messages.get(user.getId()).size();

                //这个根本就没用到
//                if(offline_messagesLength!=0) {
//                    message.setHave_offline_message(true);
//                    message.setOffline_messages(offline_messagesLength);
//                }

                objOut.writeObject(message);
                objOut.flush();



                if(offline_messagesLength!=0){
                    System.out.println(user.getId()+" 有离线消息，现在立马发送");
                    sendOffLineMessage(user.getId(),socket);
                }


                //开启线程
                UserThread userThread = new UserThread(user.getId(), socket);
                userThread.start();
                SocketThreadManager.addUserThread(user.getId(),userThread);


            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {

            //关闭服务器
            try {
                System.out.println("服务器关闭");
                server.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void sendOffLineMessage(String userId,Socket socket) throws IOException {
        ArrayList<Message> messages = ServerService.messages.get(userId);
            Iterator<Message> iterator = messages.iterator();


            //ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream());
            while (iterator.hasNext()) {
                //这个输出流在while外面创建会问题，这个用户的客户端出现大量异常
                // 注意，把listening方法中的ObjectOutputStream传过来也会出现异常
                //java.io.StreamCorruptedException: invalid stream header: 7371007E

                ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream());
                Message message = iterator.next();

                if(message.getType()==MessageStatus.GROUP_CHAT||
                        message.getType()==MessageStatus.PRIVATE_CHAT){
                    message.setType_of_chat(MessageStatus.TEXT_CHAT);
                }else if(message.getType_of_chat()==MessageStatus.GROUP_SEND_FILE||
                        message.getType_of_chat()==MessageStatus.PRIVATE_SEND_FILE){
                    message.setType_of_chat(MessageStatus.FILE_CHAT);
                }

                objOut.writeObject(message);
                objOut.flush();
            }
            messages.clear();
            System.out.println(userId+" 的离线消息发送完毕");
    }
}
